import 'dart:io';

import 'package:gate_cli/models/res_config.dart';
import 'package:gate_cli/utils/json/json_diff.dart';
import 'package:gate_cli/utils/list_extension.dart';
import 'package:gate_cli/utils/string_extension.dart';

class IntlCommandUtil {
  IntlCommandUtil._();

  static final IntlCommandUtil _instance = IntlCommandUtil._();

  static IntlCommandUtil get instance => _instance;

  String analyse(ResIntl resIntl) {
    final defDir = Directory('${resIntl.path}');
    if (!defDir.existsSync()) {
      return _result('❌未检测到国际化文件');
    }
    final defLangConfig = resIntl.defLang;
    final defLang =
        defLangConfig.endsWith('.arb') ? defLangConfig : '${defLangConfig}.arb';
    final ignoreLang = resIntl.ignoreLang.forList<String>();
    final ignoreKey = resIntl.ignoreKey.forList<String>();

    final defFile = defDir
        .listSync()
        .whereType<File>()
        .firsOrNull((e) => e.takeFileNameWithExe() == defLang);
    if (defFile == null) {
      return _result('❌未检测到默认国际化文件 $defLang');
    }

    final defJson = defFile.readAsStringSync();

    final result = defDir
        .listSync()
        .whereType<File>()

        /// 过滤隐藏文件
        .where((element) => !element.takeFileNameWithExe().startsWith('.'))

        /// 过滤默认语种 和忽略文件
        .where((element) =>
            element.takeFileNameWithExe() != defLang &&
            !ignoreLang.contains(element.takeFileNameWithoutExe()))

        /// 多语言检查
        .map((e) => _diff(defJson, e, ignoreKey))
        .toList()
        .join("\n");
    return _result(result);
  }

  String _result(String result) {
    if (result.isEmpty) return '✅未检测到异常';
    return result;
  }

  String _diff(String left, File right, List<String> ignore) {
    StringBuffer result = new StringBuffer();
    final jsonDiffer = JsonDiffer(left, right.readAsStringSync());
    jsonDiffer.ignored.addAll(ignore);
    final diff = jsonDiffer.diff();
    diff.added.forEach((key, value) {
      result.writeln('\u001b[32m + ${key} : ${value} \u001b[0m');
    });
    diff.removed.forEach((key, value) {
      result.writeln('\u001b[31m - ${key} : ${value} \u001b[0m');
    });
    diff.equals.forEach((key, value) {
      result.writeln('\u001b[33m * ${key} : ${value.first} \u001b[0m');
    });
    if (result.isNotEmpty) {
      return '${right.takeFileNameWithoutExe()}\n$result';
    }
    return result.toString();
  }
}
